home *** CD-ROM | disk | FTP | other *** search
/ Windows News 2005 November / WNnov2005.iso / Windows / Equipement / hMailServer / hMailServer-4.1-Build-136.exe / {app} / PHPWebAdmin / include / minixml / classes / element.inc.php < prev    next >
PHP Script  |  2004-10-25  |  42KB  |  1,752 lines

  1. <?php
  2.  
  3. /***************************************************************************************************
  4. ****************************************************************************************************
  5. *****
  6. *****      MiniXML - PHP class library for generating and parsing XML.
  7. *****
  8. *****      Copyright (C) 2002,2003 Patrick Deegan, Psychogenic.com
  9. *****      All rights reserved.
  10. *****
  11. *****      http://minixml.psychogenic.com
  12. *****
  13. *****   This program is free software; you can redistribute
  14. *****   it and/or modify it under the terms of the GNU
  15. *****   General Public License as published by the Free
  16. *****   Software Foundation; either version 2 of the
  17. *****   License, or (at your option) any later version.
  18. *****
  19. *****   This program is distributed in the hope that it will
  20. *****   be useful, but WITHOUT ANY WARRANTY; without even
  21. *****   the implied warranty of MERCHANTABILITY or FITNESS
  22. *****   FOR A PARTICULAR PURPOSE.  See the GNU General
  23. *****   Public License for more details.
  24. *****
  25. *****   You should have received a copy of the GNU General
  26. *****   Public License along with this program; if not,
  27. *****   write to the Free Software Foundation, Inc., 675
  28. *****   Mass Ave, Cambridge, MA 02139, USA.
  29. *****
  30. *****
  31. *****   You may contact the author, Pat Deegan, through the
  32. *****   contact section at http://www.psychogenic.com
  33. *****
  34. *****   Much more information on using this API can be found on the
  35. *****   official MiniXML website - http://minixml.psychogenic.com
  36. *****    or within the Perl version (XML::Mini) available through CPAN
  37. *****
  38. ****************************************************************************************************
  39. ***************************************************************************************************/
  40.  
  41.  
  42.  
  43. require_once(MINIXML_CLASSDIR . "/treecomp.inc.php");
  44. require_once(MINIXML_CLASSDIR . "/node.inc.php");
  45.  
  46. /***************************************************************************************************
  47. ****************************************************************************************************
  48. *****
  49. *****                      MiniXMLElement
  50. *****
  51. ****************************************************************************************************
  52. ***************************************************************************************************/
  53.  
  54.  
  55. /* class MiniXMLElement (MiniXMLTreeComponent)
  56. **
  57. ** Although the main handle to the xml document is the MiniXMLDoc object,
  58. ** much of the functionality and manipulation involves interaction with
  59. ** MiniXMLElement objects.
  60. **
  61. ** A MiniXMLElement
  62. ** has:
  63. ** - a name
  64. ** - a list of 0 or more attributes (which have a name and a value)
  65. ** - a list of 0 or more children (MiniXMLElement or MiniXMLNode objects)
  66. ** - a parent (optional, only if MINIXML_AUTOSETPARENT > 0)
  67. **/
  68.  
  69. class MiniXMLElement extends MiniXMLTreeComponent {
  70.  
  71.  
  72.     var $xname;
  73.     var $xattributes;
  74.     var $xchildren;
  75.     var $xnumChildren;
  76.     var $xnumElementChildren;
  77.  
  78.     var $xavoidLoops = MINIXML_AVOIDLOOPS;
  79.  
  80.  
  81.     /* MiniXMLElement NAME
  82.     ** Creates and inits a new MiniXMLElement
  83.     */
  84.     function MiniXMLElement ($name=NULL)
  85.     {
  86.         $this->MiniXMLTreeComponent();
  87.         $this->xname = NULL;
  88.         $this->xattributes = array();
  89.         $this->xchildren = array();
  90.         $this->xnumChildren = 0;
  91.         $this->xnumElementChildren = 0;
  92.         if ($name)
  93.         {
  94.             $this->name($name);
  95.         } else {
  96.             return _MiniXMLError("MiniXMLElement Constructor: must pass a name to constructor");
  97.         }
  98.     } /* end method MiniXMLElement */
  99.  
  100.  
  101.     /**************** Get/set methods for MiniXMLElement data *****************/
  102.  
  103.  
  104.     /* name [NEWNAME]
  105.     **
  106.     ** If a NEWNAME string is passed, the MiniXMLElement's name is set
  107.     ** to NEWNAME.
  108.     **
  109.     ** Returns the element's name.
  110.     */
  111.     function name ($setTo=NULL)
  112.     {
  113.         if (! is_null($setTo))
  114.         {
  115.             if (! is_string($setTo))
  116.             {
  117.                 return _MiniXMLError("MiniXMLElement::name() Must pass a STRING to method to set name");
  118.             }
  119.  
  120.             $this->xname = $setTo;
  121.         }
  122.  
  123.         return $this->xname;
  124.  
  125.     } /* end method name */
  126.  
  127.  
  128.  
  129.     /* attribute NAME [SETTO [SETTOALT]]
  130.     **
  131.     ** The attribute() method is used to get and set the
  132.     ** MiniXMLElement's attributes (ie the name/value pairs contained
  133.     ** within the tag, <tagname attrib1="value1" attrib2="value2">)
  134.     **
  135.     ** If SETTO is passed, the attribute's value is set to SETTO.
  136.     **
  137.     ** If the optional SETTOALT is passed and SETTO is false, the
  138.     ** attribute's value is set to SETTOALT.  This is usefull in cases
  139.     ** when you wish to set the attribute to a default value if no SETTO is
  140.     ** present, eg $myelement->attribute('href', $theHref, 'http://psychogenic.com')
  141.     ** will default to 'http://psychogenic.com'.
  142.     **
  143.     ** Note: if the MINIXML_LOWERCASEATTRIBUTES define is > 0, all attribute names
  144.     ** will be lowercased (while setting and during retrieval)
  145.     **
  146.     ** Returns the value associated with attribute NAME.
  147.     **
  148.     */
  149.     function attribute ($name, $primValue=NULL, $altValue=NULL)
  150.     {
  151.         $value = (is_null($primValue) ? $altValue : $primValue );
  152.  
  153.  
  154.         if (MINIXML_UPPERCASEATTRIBUTES > 0)
  155.         {
  156.             $name = strtoupper($name);
  157.         } elseif (MINIXML_LOWERCASEATTRIBUTES > 0)
  158.         {
  159.             $name = strtolower($name);
  160.         }
  161.  
  162.         if (! is_null($value))
  163.         {
  164.  
  165.             $this->xattributes[$name] = $value;
  166.         }
  167.  
  168.         if (! is_null($this->xattributes[$name]))
  169.         {
  170.             return $this->xattributes[$name];
  171.         } else {
  172.             return NULL;
  173.         }
  174.  
  175.     } /* end method attribute */
  176.  
  177.  
  178.     /* text [SETTO [SETTOALT]]
  179.     **
  180.     ** The text() method is used to get or append text data to this
  181.     ** element (it is appended to the child list as a new MiniXMLNode object).
  182.     **
  183.     ** If SETTO is passed, a new node is created, filled with SETTO
  184.     ** and appended to the list of this element's children.
  185.     **
  186.     ** If the optional SETTOALT is passed and SETTO is false, the
  187.     ** new node's value is set to SETTOALT.  See the attribute() method
  188.     ** for an example use.
  189.     **
  190.     ** Returns a string composed of all child MiniXMLNodes' contents.
  191.     **
  192.     ** Note: all the children MiniXMLNodes' contents - including numeric
  193.     ** nodes are included in the return string.
  194.     */
  195.     function text ($setToPrimary = NULL, $setToAlternate=NULL)
  196.     {
  197.         $setTo = ($setToPrimary ? $setToPrimary : $setToAlternate);
  198.  
  199.         if (! is_null($setTo))
  200.         {
  201.             $this->createNode($setTo);
  202.         }
  203.  
  204.         $retString = '';
  205.  
  206.         /* Extract text from all child nodes */
  207.         for($i=0; $i< $this->xnumChildren; $i++)
  208.         {
  209.             if ($this->isNode($this->xchildren[$i]))
  210.             {
  211.                 $nodeTxt = $this->xchildren[$i]->getValue();
  212.                 if (! is_null($nodeTxt))
  213.                 {
  214.                     $retString .= "$nodeTxt ";
  215.  
  216.                 } /* end if text returned */
  217.  
  218.             } /* end if this is a MiniXMLNode */
  219.  
  220.         } /* end loop over all children */
  221.  
  222.         return trim($retString);
  223.  
  224.     }  /* end method text */
  225.  
  226.  
  227.  
  228.     /* numeric [SETTO [SETTOALT]]
  229.     **
  230.     ** The numeric() method is used to get or append numeric data to
  231.     ** this element (it is appended to the child list as a MiniXMLNode object).
  232.     **
  233.     ** If SETTO is passed, a new node is created, filled with SETTO
  234.     ** and appended to the list of this element's children.
  235.     **
  236.     ** If the optional SETTOALT is passed and SETTO is false, the
  237.     ** new node's value is set to SETTOALT.  See the attribute() method
  238.     ** for an example use.
  239.     **
  240.     ** Returns a space seperated string composed all child MiniXMLNodes'
  241.     ** numeric contents.
  242.     **
  243.     ** Note: ONLY numerical contents are included from the list of child MiniXMLNodes.
  244.     **
  245.     */
  246.     function numeric ($setToPrimary = NULL, $setToAlternate=NULL)
  247.     {
  248.         $setTo = (is_null($setToPrimary) ? $setToAlternate : $setToPrimary);
  249.  
  250.         if (! is_null($setTo))
  251.         {
  252.             $this->createNode($setTo);
  253.         }
  254.  
  255.     } /* end method numeric */
  256.  
  257.  
  258.     /* comment CONTENTS
  259.     **
  260.     ** The comment() method allows you to add a new MiniXMLElementComment to this
  261.     ** element's list of children.
  262.     **
  263.     ** Comments will return a <!-- CONTENTS --> string when the element's toString()
  264.     ** method is called.
  265.     **
  266.     ** Returns a reference to the newly appended MiniXMLElementComment
  267.     **
  268.     */
  269.     function & comment ($contents)
  270.     {
  271.         $newEl = new MiniXMLElementComment();
  272.  
  273.         $appendedComment =& $this->appendChild($newEl);
  274.         $appendedComment->text($contents);
  275.  
  276.         return $appendedComment;
  277.  
  278.     } /* end method comment */
  279.  
  280.  
  281.  
  282.  
  283.  
  284.  
  285.  
  286.     /*
  287.     ** docType DEFINITION
  288.     **
  289.     ** Append a new <!DOCTYPE DEFINITION [ ...]> element as a child of this
  290.     ** element.
  291.     **
  292.     ** Returns the appended DOCTYPE element. You will normally use the returned
  293.     ** element to add ENTITY elements, like
  294.  
  295.     ** $newDocType =& $xmlRoot->docType('spec SYSTEM "spec.dtd"');
  296.     ** $newDocType->entity('doc.audience', 'public review and discussion');
  297.     */
  298.  
  299.     function & docType ($definition)
  300.     {
  301.  
  302.         $newElement = new MiniXMLElementDocType($definition);
  303.         $appendedElement =& $this->appendChild($newElement);
  304.  
  305.         return $appendedElement;
  306.     }
  307.     /*
  308.     ** entity NAME VALUE
  309.     **
  310.     ** Append a new <!ENTITY NAME "VALUE"> element as a child of this
  311.     ** element.
  312.  
  313.     ** Returns the appended ENTITY element.
  314.     */
  315.     function & entity ($name,$value)
  316.     {
  317.  
  318.         $newElement = new MiniXMLElementEntity($name, $value);
  319.         $appendedEl =& $this->appendChild($newElement);
  320.  
  321.         return $appendedEl;
  322.     }
  323.  
  324.  
  325.     /*
  326.     ** cdata CONTENTS
  327.     **
  328.     ** Append a new <![CDATA[ CONTENTS ]]> element as a child of this element.
  329.     ** Returns the appended CDATA element.
  330.     **
  331.     */
  332.  
  333.     function & cdata ($contents)
  334.     {
  335.         $newElement = new MiniXMLElementCData($contents);
  336.         $appendedChild =& $this->appendChild($newElement);
  337.  
  338.         return $appendedChild;
  339.     }
  340.  
  341.  
  342.     /* getValue
  343.     **
  344.     ** Returns a string containing the value of all the element's
  345.     ** child MiniXMLNodes (and all the MiniXMLNodes contained within
  346.     ** it's child MiniXMLElements, recursively).
  347.     **
  348.     ** Note: the seperator parameter remains officially undocumented
  349.     ** since I'm not sure it will remain part of the API
  350.     */
  351.     function getValue ($seperator=' ')
  352.     {
  353.         $retStr = '';
  354.         $valArray = array();
  355.         for($i=0; $i < $this->xnumChildren; $i++)
  356.         {
  357.             $value = $this->xchildren[$i]->getValue();
  358.             if (! is_null($value))
  359.             {
  360.                 array_push($valArray, $value);
  361.             }
  362.         }
  363.         if (count($valArray))
  364.         {
  365.             $retStr = implode($seperator, $valArray);
  366.         }
  367.         return $retStr;
  368.  
  369.     } /* end method getValue */
  370.  
  371.  
  372.  
  373.     /* getElement NAME
  374.     ** Searches the element and it's children for an element with name NAME.
  375.     **
  376.     ** Returns a reference to the first MiniXMLElement with name NAME,
  377.     ** if found, NULL otherwise.
  378.     **
  379.     ** NOTE: The search is performed like this, returning the first
  380.     **      element that matches:
  381.     **
  382.     ** - Check this element for a match
  383.     ** - Check this element's immediate children (in order) for a match.
  384.     ** - Ask each immediate child (in order) to MiniXMLElement::getElement()
  385.     **  (each child will then proceed similarly, checking all it's immediate
  386.     **   children in order and then asking them to getElement())
  387.     */
  388.     function &getElement ($name)
  389.     {
  390.  
  391.         if (MINIXML_DEBUG > 0)
  392.         {
  393.             $elname = $this->name();
  394.             _MiniXMLLog("MiniXMLElement::getElement() called for $name on $elname.");
  395.         }
  396.         if (is_null($name))
  397.         {
  398.             return _MiniXMLError("MiniXMLElement::getElement() Must Pass Element name.");
  399.         }
  400.  
  401.  
  402.         /** Must only check children as checking $this results in an inability to
  403.         *** fetch nested objects with the same name
  404.         *** <tag>
  405.         ***  <nested>
  406.         ***   <nested>
  407.         ***     Can't get here from tag or from the first 'nested'
  408.         ***   </nested>
  409.         ***  </nested>
  410.         *** </tag>
  411.         if (MINIXML_CASESENSITIVE > 0)
  412.         {
  413.             if (strcmp($this->xname, $name) == 0)
  414.             {
  415.                 /* This element is it * /
  416.                 return $this;
  417.             }
  418.         } else {
  419.  
  420.             if (strcasecmp($this->xname,$name) == 0)
  421.             {
  422.                 return $this;
  423.             }
  424.         }
  425.  
  426.         ***** end commented out section ****
  427.         */
  428.  
  429.         if (! $this->xnumChildren )
  430.         {
  431.             /* Not match here and and no kids - not found... */
  432.             return NULL;
  433.         }
  434.  
  435.         /* Try each child (immediate children take priority) */
  436.         for ($i = 0; $i < $this->xnumChildren; $i++)
  437.         {
  438.             $childname = $this->xchildren[$i]->name();
  439.             if ($childname)
  440.             {
  441.                 if (MINIXML_CASESENSITIVE > 0)
  442.                 {
  443.                     /* case sensitive matches only */
  444.                     if (strcmp($name, $childname) == 0)
  445.                     {
  446.                         return $this->xchildren[$i];
  447.                     }
  448.                 } else {
  449.                     /* case INsensitive matching */
  450.                     if (strcasecmp($name, $childname) == 0)
  451.                     {
  452.                         return $this->xchildren[$i];
  453.                     }
  454.                 } /* end if case sensitive */
  455.             } /* end if child has a name */
  456.  
  457.         } /* end loop over all my children */
  458.  
  459.         /* Use beautiful recursion, daniel san */
  460.         for ($i = 0; $i < $this->xnumChildren; $i++)
  461.         {
  462.             $theelement = $this->xchildren[$i]->getElement($name);
  463.             if ($theelement)
  464.             {
  465.                 if (MINIXML_DEBUG > 0)
  466.                 {
  467.                     _MiniXMLLog("MiniXMLElement::getElement() returning element $theelement");
  468.                 }
  469.                 return $theelement;
  470.             }
  471.         }
  472.  
  473.         /* Not found */
  474.         return NULL;
  475.  
  476.  
  477.     }  /* end method getElement */
  478.  
  479.  
  480.     /* getElementByPath PATH
  481.     ** Attempts to return a reference to the (first) element at PATH
  482.     ** where PATH is the path in the structure (relative to this element) to
  483.     ** the requested element.
  484.     **
  485.     ** For example, in the document represented by:
  486.     **
  487.     **     <partRateRequest>
  488.     **      <vendor>
  489.     **       <accessid user="myusername" password="mypassword" />
  490.     **      </vendor>
  491.     **      <partList>
  492.     **       <partNum>
  493.     **        DA42
  494.     **       </partNum>
  495.     **       <partNum>
  496.     **        D99983FFF
  497.     **       </partNum>
  498.     **       <partNum>
  499.     **        ss-839uent
  500.     **       </partNum>
  501.     **      </partList>
  502.     **     </partRateRequest>
  503.     **
  504.     **    $partRate =& $xmlDocument->getElement('partRateRequest');
  505.     **
  506.     **     $accessid =& $partRate->getElementByPath('vendor/accessid');
  507.     **
  508.     ** Will return what you expect (the accessid element with attributes user = "myusername"
  509.     ** and password = "mypassword").
  510.     **
  511.     ** BUT be careful:
  512.     **    $accessid =& $partRate->getElementByPath('partList/partNum');
  513.     **
  514.     ** will return the partNum element with the value "DA42".  Other partNums are
  515.     ** inaccessible by getElementByPath() - Use MiniXMLElement::getAllChildren() instead.
  516.     **
  517.     ** Returns the MiniXMLElement reference if found, NULL otherwise.
  518.     */
  519.     function &getElementByPath($path)
  520.     {
  521.         $names = split ("/", $path);
  522.  
  523.         $element = $this;
  524.         foreach ($names as $elementName)
  525.         {
  526.             if ($element && $elementName) /* Make sure we didn't hit a dead end and that we have a name*/
  527.             {
  528.                 /* Ask this element to get the next child in path */
  529.                 $element = $element->getElement($elementName);
  530.             }
  531.         }
  532.  
  533.         return $element;
  534.  
  535.     } /* end method getElementByPath */
  536.  
  537.  
  538.  
  539.     /* numChildren [NAMED]
  540.     **
  541.     ** Returns the number of immediate children for this element
  542.     **
  543.     ** If the optional NAMED parameter is passed, returns only the
  544.     ** number of immediate children named NAMED.
  545.     */
  546.     function numChildren ($named=NULL)
  547.     {
  548.         if (is_null($named))
  549.         {
  550.             return $this->xnumElementChildren;
  551.         }
  552.  
  553.         /* We require only children named '$named' */
  554.         $allkids =& $this->getAllChildren($named);
  555.  
  556.         return count($allkids);
  557.  
  558.  
  559.     }
  560.  
  561.  
  562.     /* getAllChildren [NAME]
  563.     **
  564.     ** Returns a reference to an array of all this element's MiniXMLElement children
  565.     **
  566.     ** Note: although the MiniXMLElement may contain MiniXMLNodes as children, these are
  567.     ** not part of the returned list.
  568.     **/
  569.     function &getAllChildren ($name=NULL)
  570.     {
  571.         $retArray = array();
  572.         $count = 0;
  573.  
  574.         if (is_null($name))
  575.         {
  576.             /* Return all element children */
  577.             for($i=0; $i < $this->xnumChildren; $i++)
  578.             {
  579.                 if (method_exists($this->xchildren[$i], 'MiniXMLElement'))
  580.                 {
  581.                     $retArray[$count++] = $this->xchildren[$i];
  582.                 }
  583.             }
  584.         } else {
  585.             /* Return only element children with name $name */
  586.  
  587.             for($i=0; $i < $this->xnumChildren; $i++)
  588.             {
  589.                 if (method_exists($this->xchildren[$i], 'MiniXMLElement'))
  590.                 {
  591.                     if (MINIXML_CASESENSITIVE > 0)
  592.                     {
  593.                         if ($this->xchildren[$i]->name() == $name)
  594.                         {
  595.                             $retArray[$count++] = $this->xchildren[$i];
  596.                         }
  597.                     } else {
  598.                         if (strcasecmp($this->xchildren[$i]->name(), $name) == 0)
  599.                         {
  600.                             $retArray[$count++] = $this->xchildren[$i];
  601.                         }
  602.                     } /* end if case sensitive */
  603.  
  604.                 } /* end if child is a MiniXMLElement object */
  605.  
  606.             } /* end loop over all children */
  607.  
  608.         } /* end if specific name was requested */
  609.  
  610.         return $retArray;
  611.  
  612.     } /* end method getAllChildren */
  613.  
  614.  
  615.  
  616.     function &insertChild (&$child, $idx=0)
  617.     {
  618.  
  619.  
  620.  
  621.         if (! $this->_validateChild($child))
  622.         {
  623.             return;
  624.         }
  625.  
  626.         /* Set the parent for the child element to this element if
  627.         ** avoidLoops or MINIXML_AUTOSETPARENT is set
  628.         */
  629.         if ($this->xavoidLoops || (MINIXML_AUTOSETPARENT > 0) )
  630.         {
  631.             if ($this->xparent == $child)
  632.             {
  633.  
  634.                 $cname = $child->name();
  635.                 return _MiniXMLError("MiniXMLElement::insertChild() Tryng to append parent $cname as child of "
  636.                             . $this->xname );
  637.             }
  638.             $child->parent($this);
  639.         }
  640.  
  641.  
  642.         $nextIdx = $this->xnumChildren;
  643.         $lastIdx = $nextIdx - 1;
  644.         if ($idx > $lastIdx)
  645.         {
  646.  
  647.             if ($idx > $nextIdx)
  648.             {
  649.                 $idx = $lastIdx + 1;
  650.             }
  651.             $this->xchildren[$idx] = $child;
  652.             $this->xnumChildren++;
  653.             if ($this->isElement($child))
  654.             {
  655.                 $this->xnumElementChildren++;
  656.             }
  657.  
  658.         } elseif ($idx >= 0)
  659.         {
  660.  
  661.             $removed = array_splice($this->xchildren, $idx);
  662.             array_push($this->xchildren, $child);
  663.             $numRemoved = count($removed);
  664.  
  665.             for($i=0; $i<$numRemoved; $i++)
  666.             {
  667.  
  668.                 array_push($this->xchildren, $removed[$i]);
  669.             }
  670.             $this->xnumChildren++;
  671.             if ($this->isElement($child))
  672.             {
  673.                 $this->xnumElementChildren++;
  674.             }
  675.  
  676.  
  677.         } else {
  678.             $revIdx = (-1 * $idx) % $this->xnumChildren;
  679.             $newIdx = $this->xnumChildren - $revIdx;
  680.  
  681.             if ($newIdx < 0)
  682.             {
  683.                 return _MiniXMLError("Element::insertChild() Ended up with a negative index? ($newIdx)");
  684.             }
  685.  
  686.             return $this->insertChild($child, $newIdx);
  687.         }
  688.  
  689.         return $child;
  690.     }
  691.  
  692.  
  693.     /* appendChild CHILDELEMENT
  694.     **
  695.     ** appendChild is used to append an existing MiniXMLElement object to
  696.     ** this element's list.
  697.     **
  698.     ** Returns a reference to the appended child element.
  699.     **
  700.     ** NOTE: Be careful not to create loops in the hierarchy, eg
  701.     ** $parent->appendChild($child);
  702.     ** $child->appendChild($subChild);
  703.     ** $subChild->appendChild($parent);
  704.     **
  705.     ** If you want to be sure to avoid loops, set the MINIXML_AVOIDLOOPS define
  706.     ** to 1 or use the avoidLoops() method (will apply to all children added with createChild())
  707.     */
  708.     function &appendChild (&$child)
  709.     {
  710.  
  711.         if (! $this->_validateChild($child))
  712.         {
  713.             return;
  714.         }
  715.  
  716.         /* Set the parent for the child element to this element if
  717.         ** avoidLoops or MINIXML_AUTOSETPARENT is set
  718.         */
  719.         if ($this->xavoidLoops || (MINIXML_AUTOSETPARENT > 0) )
  720.         {
  721.             if ($this->xparent == $child)
  722.             {
  723.  
  724.                 $cname = $child->name();
  725.                 return _MiniXMLError("MiniXMLElement::appendChild() Tryng to append parent $cname as child of "
  726.                             . $this->xname );
  727.             }
  728.             $child->parent($this);
  729.         }
  730.  
  731.  
  732.         $this->xnumElementChildren++; /* Note that we're addind a MiniXMLElement child */
  733.  
  734.         /* Add the child to the list */
  735.         $idx = $this->xnumChildren++;
  736.         $this->xchildren[$idx] =& $child;
  737.  
  738.         return $this->xchildren[$idx];
  739.  
  740.     } /* end method appendChild */
  741.  
  742.  
  743.     /* prependChild CHILDELEMENT
  744.     **
  745.     ** prependChild is used to prepend an existing MiniXMLElement object to
  746.     ** this element's list.  The child will be positioned at the begining of
  747.     ** the elements child list, thus it will be output first in the resulting XML.
  748.     **
  749.     ** Returns a reference to the prepended child element.
  750.     */
  751.     function &prependChild ($child)
  752.     {
  753.  
  754.  
  755.         $this->_validateChild($child);
  756.  
  757.         /* Set the parent for the child element to this element if
  758.         ** avoidLoops or MINIXML_AUTOSETPARENT is set
  759.         */
  760.         if ($this->xavoidLoops || (MINIXML_AUTOSETPARENT > 0) )
  761.         {
  762.             if ($this->xparent == $child)
  763.             {
  764.  
  765.                 $cname = $child->name();
  766.                 return _MiniXMLError("MiniXMLElement::appendChild() Tryng to append parent $cname as child of "
  767.                             . $this->xname );
  768.             }
  769.             $child->parent($this);
  770.         }
  771.  
  772.  
  773.         $this->xnumElementChildren++; /* Note that we're adding a MiniXMLElement child */
  774.  
  775.         /* Add the child to the list */
  776.         $idx = $this->xnumChildren++;
  777.         array_unshift($this->xchildren, $child);
  778.         return $this->xchildren[0];
  779.  
  780.     } /* end method prependChild */
  781.  
  782.     function _validateChild (&$child)
  783.     {
  784.  
  785.         if (is_null($child))
  786.         {
  787.             return  _MiniXMLError("MiniXMLElement::_validateChild() need to pass a non-NULL MiniXMLElement child.");
  788.         }
  789.  
  790.         if (! method_exists($child, 'MiniXMLElement'))
  791.         {
  792.             return _MiniXMLError("MiniXMLElement::_validateChild() must pass a MiniXMLElement object to _validateChild.");
  793.         }
  794.  
  795.         /* Make sure element is named */
  796.         $cname = $child->name();
  797.         if (is_null($cname))
  798.         {
  799.             return _MiniXMLError("MiniXMLElement::_validateChild() children must be named");
  800.         }
  801.  
  802.  
  803.         /* Check for loops */
  804.         if ($child == $this)
  805.         {
  806.             return _MiniXMLError("MiniXMLElement::_validateChild() Trying to append self as own child!");
  807.         } elseif ( $this->xavoidLoops && $child->parent())
  808.         {
  809.             return _MiniXMLError("MiniXMLElement::_validateChild() Trying to append a child ($cname) that already has a parent set "
  810.                         . "while avoidLoops is on - aborting");
  811.         }
  812.  
  813.         return 1;
  814.     }
  815.     /* createChild ELEMENTNAME [VALUE]
  816.     **
  817.     ** Creates a new MiniXMLElement instance and appends it to the list
  818.     ** of this element's children.
  819.     ** The new child element's name is set to ELEMENTNAME.
  820.     **
  821.     ** If the optional VALUE (string or numeric) parameter is passed,
  822.     ** the new element's text/numeric content will be set using VALUE.
  823.     **
  824.     ** Returns a reference to the new child element
  825.     **
  826.     ** Note: don't forget to use the =& (reference assignment) operator
  827.     ** when calling createChild:
  828.     **
  829.     **    $newChild =& $myElement->createChild('newChildName');
  830.     **
  831.     */
  832.     function & createChild ($name, $value=NULL)
  833.     {
  834.         if (! $name)
  835.         {
  836.             return _MiniXMLError("MiniXMLElement::createChild() Must pass a NAME to createChild.");
  837.         }
  838.  
  839.         if (! is_string($name))
  840.         {
  841.             return _MiniXMLError("MiniXMLElement::createChild() Name of child must be a STRING");
  842.         }
  843.  
  844.         $child =& new MiniXMLElement($name);
  845.  
  846.         $appendedChild =& $this->appendChild($child);
  847.  
  848.         if (! is_null($value))
  849.         {
  850.             if (is_numeric($value))
  851.             {
  852.                 $appendedChild->numeric($value);
  853.             } elseif (is_string($value))
  854.             {
  855.                 $appendedChild->text($value);
  856.             }
  857.         }
  858.  
  859.         $appendedChild->avoidLoops($this->xavoidLoops);
  860.  
  861.         return $appendedChild;
  862.  
  863.     } /* end method createChild */
  864.  
  865.  
  866.  
  867.     /* removeChild CHILD
  868.     ** Removes CHILD from this element's list of children.
  869.     **
  870.     ** Returns the removed child, if found, NULL otherwise.
  871.     */
  872.  
  873.     function &removeChild (&$child)
  874.     {
  875.         if (! $this->xnumChildren)
  876.         {
  877.             if (MINIXML_DEBUG > 0)
  878.             {
  879.                 _MiniXMLLog("Element::removeChild() called for element without any children.") ;
  880.             }
  881.             return NULL;
  882.         }
  883.  
  884.         $foundChild;
  885.         $idx = 0;
  886.         while ($idx < $this->xnumChildren && ! $foundChild)
  887.         {
  888.             if ($this->xchildren[$idx] == $child)
  889.             {
  890.                 $foundChild =& $this->xchildren[$idx];
  891.             } else {
  892.                 $idx++;
  893.             }
  894.         }
  895.  
  896.         if (! $foundChild)
  897.         {
  898.             if (MINIXML_DEBUG > 0)
  899.             {
  900.                 _MiniXMLLog("Element::removeChild() No matching child found.") ;
  901.             }
  902.             return NULL;
  903.         }
  904.  
  905.         array_splice($this->xchildren, $idx, 1);
  906.  
  907.         $this->xnumChildren--;
  908.         if ($this->isElement($foundChild))
  909.         {
  910.             $this->xnumElementChildren--;
  911.         }
  912.  
  913.         unset ($foundChild->xparent) ;
  914.         return $foundChild;
  915.     }
  916.  
  917.  
  918.     /* removeAllChildren
  919.     ** Removes all children of this element.
  920.     **
  921.     ** Returns an array of the removed children (which may be empty)
  922.     */
  923.     function &removeAllChildren ()
  924.     {
  925.         $emptyArray = array();
  926.  
  927.         if (! $this->xnumChildren)
  928.         {
  929.             return $emptyArray;
  930.         }
  931.  
  932.         $retList =& $this->xchildren;
  933.  
  934.         $idx = 0;
  935.         while ($idx < $this->xnumChildren)
  936.         {
  937.             unset ($retList[$idx++]->xparent);
  938.         }
  939.  
  940.         $this->xchildren = array();
  941.         $this->xnumElementChildren = 0;
  942.         $this->xnumChildren = 0;
  943.  
  944.  
  945.         return $retList;
  946.     }
  947.  
  948.  
  949.     function & remove ()
  950.     {
  951.         $parent =& $this->parent();
  952.  
  953.         if (!$parent)
  954.         {
  955.             if (MINIXML_DEBUG > 0)
  956.                 _MiniXMLLog("XML::Mini::Element::remove() called for element with no parent set.  Aborting.");
  957.             return NULL;
  958.         }
  959.  
  960.         $removed =& $parent->removeChild($this);
  961.  
  962.         return $removed;
  963.     }
  964.  
  965.  
  966.  
  967.     /* parent NEWPARENT
  968.     **
  969.     ** The parent() method is used to get/set the element's parent.
  970.     **
  971.     ** If the NEWPARENT parameter is passed, sets the parent to NEWPARENT
  972.     ** (NEWPARENT must be an instance of MiniXMLElement)
  973.     **
  974.     ** Returns a reference to the parent MiniXMLElement if set, NULL otherwise.
  975.     **
  976.     ** Note: This method is mainly used internally and you wouldn't normally need
  977.     ** to use it.
  978.     ** It get's called on element appends when MINIXML_AUTOSETPARENT or
  979.     ** MINIXML_AVOIDLOOPS or avoidLoops() > 1
  980.     **
  981.     */
  982.     function &parent (&$setParent)
  983.     {
  984.         if (! is_null($setParent))
  985.         {
  986.             /* Parents can only be MiniXMLElement objects */
  987.             if (! $this->isElement($setParent))
  988.             {
  989.                 return _MiniXMLError("MiniXMLElement::parent(): Must pass an instance of MiniXMLElement to set.");
  990.             }
  991.             $this->xparent = $setParent;
  992.         }
  993.  
  994.         return $this->xparent;
  995.  
  996.     } /* end method parent */
  997.  
  998.  
  999.     /* avoidLoops SETTO
  1000.     **
  1001.     ** The avoidLoops() method is used to get or set the avoidLoops flag for this element.
  1002.     **
  1003.     ** When avoidLoops is true, children with parents already set can NOT be appended to any
  1004.     ** other elements.  This is overkill but it is a quick and easy way to avoid infinite loops
  1005.     ** in the heirarchy.
  1006.     **
  1007.     ** The avoidLoops default behavior is configured with the MINIXML_AVOIDLOOPS define but can be
  1008.     ** set on individual elements (and automagically all the element's children) with the
  1009.     ** avoidLoops() method.
  1010.     **
  1011.     ** Returns the current value of the avoidLoops flag for the element.
  1012.     **
  1013.     */
  1014.     function avoidLoops ($setTo = NULL)
  1015.     {
  1016.         if (! is_null($setTo))
  1017.         {
  1018.             $this->xavoidLoops = $setTo;
  1019.         }
  1020.  
  1021.         return $this->xavoidLoops;
  1022.     }
  1023.  
  1024.  
  1025.     /* toString [SPACEOFFSET]
  1026.     **
  1027.     ** toString returns an XML string based on the element's attributes,
  1028.     ** and content (recursively doing the same for all children)
  1029.     **
  1030.     ** The optional SPACEOFFSET parameter sets the number of spaces to use
  1031.     ** after newlines for elements at this level (adding 1 space per level in
  1032.     ** depth).  SPACEOFFSET defaults to 0.
  1033.     **
  1034.     ** If SPACEOFFSET is passed as MINIXML_NOWHITESPACES.
  1035.     ** no \n or whitespaces will be inserted in the xml string
  1036.     ** (ie it will all be on a single line with no spaces between the tags.
  1037.     **
  1038.     ** Returns the XML string.
  1039.     **
  1040.     **
  1041.     ** Note: Since the toString() method recurses into child elements and because
  1042.     ** of the MINIXML_NOWHITESPACES and our desire to avoid testing for this value
  1043.     ** on every element (as it does not change), here we split up the toString method
  1044.     ** into 2 subs: toStringWithWhiteSpaces(DEPTH) and toStringNoWhiteSpaces().
  1045.     **
  1046.     ** Each of these methods, which are to be considered private (?), in turn recurses
  1047.     ** calling the appropriate With/No WhiteSpaces toString on it's children - thereby
  1048.     ** avoiding the test on SPACEOFFSET
  1049.     */
  1050.  
  1051.     function toString ($depth=0)
  1052.     {
  1053.         if ($depth == MINIXML_NOWHITESPACES)
  1054.         {
  1055.             return $this->toStringNoWhiteSpaces();
  1056.         } else {
  1057.             return $this->toStringWithWhiteSpaces($depth);
  1058.         }
  1059.     }
  1060.  
  1061.     function toStringWithWhiteSpaces ($depth=0)
  1062.     {
  1063.         $attribString = '';
  1064.         $elementName = $this->xname;
  1065.         $spaces = $this->_spaceStr($depth) ;
  1066.  
  1067.         $retString = "$spaces<$elementName";
  1068.  
  1069.  
  1070.         foreach ($this->xattributes as $attrname => $attrvalue)
  1071.         {
  1072.             $attribString .= "$attrname=\"$attrvalue\" ";
  1073.         }
  1074.  
  1075.  
  1076.         if ($attribString)
  1077.         {
  1078.             $attribString = rtrim($attribString);
  1079.             $retString .= " $attribString";
  1080.         }
  1081.  
  1082.         if (! $this->xnumChildren)
  1083.         {
  1084.             /* No kids -> no sub-elements, no text, nothing - consider a <unary/> element */
  1085.             $retString .= " />\n";
  1086.  
  1087.             return $retString;
  1088.         }
  1089.  
  1090.  
  1091.  
  1092.         /* If we've gotten this far, the element has
  1093.         ** kids or text - consider a <binary>otherstuff</binary> element
  1094.         */
  1095.  
  1096.         $onlyTxtChild = 0;
  1097.         if ($this->xnumChildren == 1 && ! $this->xnumElementChildren)
  1098.         {
  1099.             $onlyTxtChild = 1;
  1100.         }
  1101.  
  1102.  
  1103.  
  1104.         if ($onlyTxtChild)
  1105.         {
  1106.             $nextDepth = 0;
  1107.             $retString .= "> ";
  1108.         } else {
  1109.             $nextDepth = $depth+1;
  1110.             $retString .= ">\n";
  1111.         }
  1112.  
  1113.  
  1114.  
  1115.         for ($i=0; $i < $this->xnumChildren ; $i++)
  1116.         {
  1117.             if (method_exists($this->xchildren[$i], 'toStringWithWhiteSpaces') )
  1118.             {
  1119.  
  1120.                 $newStr = $this->xchildren[$i]->toStringWithWhiteSpaces($nextDepth);
  1121.  
  1122.  
  1123.                 if (! is_null($newStr))
  1124.                 {
  1125.                     if (! ( preg_match("/\n\$/", $newStr) || $onlyTxtChild) )
  1126.                     {
  1127.                         $newStr .= "\n";
  1128.                     }
  1129.  
  1130.                     $retString .= $newStr;
  1131.                 }
  1132.  
  1133.             } else {
  1134.                 if (MINIXML_DEBUG > 0)
  1135.                     _MiniXMLLog("Invalid child found in $elementName ". $this->xchildren[$i]->name() );
  1136.  
  1137.             } /* end if has a toString method */
  1138.  
  1139.         } /* end loop over all children */
  1140.  
  1141.         /* add the indented closing tag */
  1142.         if ($onlyTxtChild)
  1143.         {
  1144.             $retString .= " </$elementName>\n";
  1145.         } else {
  1146.             $retString .= "$spaces</$elementName>\n";
  1147.         }
  1148.         return $retString;
  1149.  
  1150.     } /* end method toString */
  1151.  
  1152.  
  1153.  
  1154.  
  1155.     function toStringNoWhiteSpaces ()
  1156.     {
  1157.         $retString = '';
  1158.         $attribString = '';
  1159.         $elementName = $this->xname;
  1160.  
  1161.         foreach ($this->xattributes as $attrname => $attrvalue)
  1162.         {
  1163.             $attribString .= "$attrname=\"$attrvalue\" ";
  1164.         }
  1165.  
  1166.         $retString = "<$elementName";
  1167.  
  1168.  
  1169.         if ($attribString)
  1170.         {
  1171.             $attribString = rtrim($attribString);
  1172.             $retString .= " $attribString";
  1173.         }
  1174.  
  1175.         if (! $this->xnumChildren)
  1176.         {
  1177.             /* No kids -> no sub-elements, no text, nothing - consider a <unary/> element */
  1178.  
  1179.             $retString .= " />";
  1180.             return $retString;
  1181.         }
  1182.  
  1183.  
  1184.         /* If we've gotten this far, the element has
  1185.         ** kids or text - consider a <binary>otherstuff</binary> element
  1186.         */
  1187.         $retString .= ">";
  1188.  
  1189.         /* Loop over all kids, getting associated strings */
  1190.         for ($i=0; $i < $this->xnumChildren ; $i++)
  1191.         {
  1192.             if (method_exists($this->xchildren[$i], 'toStringNoWhiteSpaces') )
  1193.             {
  1194.                 $newStr = $this->xchildren[$i]->toStringNoWhiteSpaces();
  1195.  
  1196.                 if (! is_null($newStr))
  1197.                 {
  1198.                     $retString .= $newStr;
  1199.                 }
  1200.  
  1201.             } else {
  1202.                 if (MINIXML_DEBUG > 0)
  1203.                     _MiniXMLLog("Invalid child found in $elementName");
  1204.  
  1205.             } /* end if has a toString method */
  1206.  
  1207.         } /* end loop over all children */
  1208.  
  1209.         /* add the indented closing tag */
  1210.         $retString .= "</$elementName>";
  1211.  
  1212.         return $retString;
  1213.  
  1214.     } /* end method toStringNoWhiteSpaces */
  1215.  
  1216.  
  1217.     /* toStructure
  1218.     **
  1219.     ** Converts an element to a structure - either an array or a simple string.
  1220.     **
  1221.     ** This method is used by MiniXML documents to perform their toArray() magic.
  1222.     */
  1223.     function toStructure ()
  1224.     {
  1225.  
  1226.         $retHash = array();
  1227.         $contents = "";
  1228.         $numAdded = 0;
  1229.  
  1230.  
  1231.         foreach ($this->xattributes as $attrname => $attrvalue)
  1232.         {
  1233.             $retHash[$attrname] = $attrvalue;
  1234.             $numAdded++;
  1235.         }
  1236.  
  1237.  
  1238.         for($i=0; $i< $this->xnumChildren; $i++)
  1239.         {
  1240.             if ($this->isElement($this->xchildren[$i]))
  1241.             {
  1242.                 $name = $this->xchildren[$i]->name();
  1243.  
  1244.  
  1245.                 $struct = $this->xchildren[$i]->toStructure();
  1246.                 $existing = NULL;
  1247.                 if (isset($retHash[$name]))
  1248.                 {
  1249.                     $existing =& $retHash[$name];
  1250.                 }
  1251.  
  1252.  
  1253.                 if ($existing)
  1254.                 {
  1255.                     if (_MiniXML_NumKeyArray($existing))
  1256.                     {
  1257.                         array_push($existing, $struct);
  1258.                     } else {
  1259.                         $newArray = array();
  1260.                         array_push($newArray, $existing);
  1261.                         array_push($newArray, $struct);
  1262.                         $retHash[$name] =& $newArray;
  1263.                     }
  1264.                 } else {
  1265.  
  1266.                     $retHash[$name] = $struct;
  1267.  
  1268.                 }
  1269.  
  1270.  
  1271.                 $numAdded++;
  1272.             } else {
  1273.                 $contents .= $this->xchildren[$i]->getValue();
  1274.             }
  1275.  
  1276.  
  1277.         }
  1278.  
  1279.  
  1280.         if ($numAdded)
  1281.         {
  1282.             if (! empty($contents))
  1283.             {
  1284.                 $retHash['-content'] = $contents;
  1285.             }
  1286.  
  1287.             return $retHash;
  1288.         } else {
  1289.             return $contents;
  1290.         }
  1291.  
  1292.     } // end toStructure() method
  1293.  
  1294.  
  1295.  
  1296.  
  1297.  
  1298.     /* isElement ELEMENT
  1299.     ** Returns a true value if ELEMENT is an instance of MiniXMLElement,
  1300.     ** false otherwise.
  1301.     **
  1302.     ** Note: Used internally.
  1303.     */
  1304.     function isElement (&$testme)
  1305.     {
  1306.         if (is_null($testme))
  1307.         {
  1308.             return 0;
  1309.         }
  1310.  
  1311.         return method_exists($testme, 'MiniXMLElement');
  1312.     }
  1313.  
  1314.  
  1315.     /* isNode NODE
  1316.     ** Returns a true value if NODE is an instance of MiniXMLNode,
  1317.     ** false otherwise.
  1318.     **
  1319.     ** Note: used internally.
  1320.     */
  1321.     function isNode (&$testme)
  1322.     {
  1323.         if (is_null($testme))
  1324.         {
  1325.             return 0;
  1326.         }
  1327.  
  1328.         return method_exists($testme, 'MiniXMLNode');
  1329.     }
  1330.  
  1331.  
  1332.     /* createNode NODEVALUE [ESCAPEENTITIES]
  1333.     **
  1334.     ** Private (?)
  1335.     **
  1336.     ** Creates a new MiniXMLNode instance and appends it to the list
  1337.     ** of this element's children.
  1338.     ** The new child node's value is set to NODEVALUE.
  1339.     **
  1340.     ** Returns a reference to the new child node.
  1341.     **
  1342.     ** Note: You don't need to use this method normally - it is used
  1343.     ** internally when appending text() and such data.
  1344.     **
  1345.     */
  1346.     function & createNode (&$value, $escapeEntities=NULL)
  1347.     {
  1348.  
  1349.         $newNode = new MiniXMLNode($value, $escapeEntities);
  1350.  
  1351.         $appendedNode =& $this->appendNode($newNode);
  1352.  
  1353.         return $appendedNode;
  1354.     }
  1355.  
  1356.  
  1357.     /* appendNode CHILDNODE
  1358.     **
  1359.     ** appendNode is used to append an existing MiniXMLNode object to
  1360.     ** this element's list.
  1361.     **
  1362.     ** Returns a reference to the appended child node.
  1363.     **
  1364.     **
  1365.     ** Note: You don't need to use this method normally - it is used
  1366.     ** internally when appending text() and such data.
  1367.     */
  1368.     function &appendNode (&$node)
  1369.     {
  1370.         if (is_null($node))
  1371.         {
  1372.             return  _MiniXMLError("MiniXMLElement::appendNode() need to pass a non-NULL MiniXMLNode.");
  1373.         }
  1374.  
  1375.  
  1376.         if (! method_exists($node, 'MiniXMLNode'))
  1377.         {
  1378.             return _MiniXMLError("MiniXMLElement::appendNode() must pass a MiniXMLNode object to appendNode.");
  1379.         }
  1380.  
  1381.         if (MINIXML_AUTOSETPARENT)
  1382.         {
  1383.             if ($this->xparent == $node)
  1384.             {
  1385.                 return _MiniXMLError("MiniXMLElement::appendnode() Tryng to append parent $cname as node of "
  1386.                             . $this->xname );
  1387.             }
  1388.             $node->parent($this);
  1389.         }
  1390.  
  1391.  
  1392.         $idx = $this->xnumChildren++;
  1393.         $this->xchildren[$idx] = $node;
  1394.  
  1395.         return $this->xchildren[$idx];
  1396.  
  1397.  
  1398.     }
  1399.  
  1400.  
  1401.  
  1402.  
  1403. } /* end MiniXMLElement class definition */
  1404.  
  1405.  
  1406.  
  1407.  
  1408.  
  1409.  
  1410. /***************************************************************************************************
  1411. ****************************************************************************************************
  1412. *****
  1413. *****                      MiniXMLElementComment
  1414. *****
  1415. ****************************************************************************************************
  1416. ***************************************************************************************************/
  1417.  
  1418. /* The MiniXMLElementComment class is a specific extension of the MiniXMLElement class.
  1419. **
  1420. ** It is used to create the special <!-- comment --> tags and an instance in created when calling
  1421. ** $elementObject->comment('this is a comment');
  1422. **
  1423. ** It's methods are the same as for MiniXMLElement - see those for documentation.
  1424. **/
  1425.  
  1426. class MiniXMLElementComment extends MiniXMLElement {
  1427.  
  1428.     function MiniXMLElementComment ($name=NULL)
  1429.     {
  1430.         $this->MiniXMLElement('!--');
  1431.     }
  1432.  
  1433.  
  1434.     function toString ($depth=0)
  1435.     {
  1436.         if ($depth == MINIXML_NOWHITESPACES)
  1437.         {
  1438.             return $this->toStringNoWhiteSpaces();
  1439.         } else {
  1440.             return $this->toStringWithWhiteSpaces($depth);
  1441.         }
  1442.     }
  1443.  
  1444.  
  1445.     function toStringWithWhiteSpaces ($depth=0)
  1446.     {
  1447.  
  1448.         $spaces = $this->_spaceStr($depth) ;
  1449.  
  1450.         $retString = "$spaces<!-- \n";
  1451.  
  1452.         if (! $this->xnumChildren)
  1453.         {
  1454.             /* No kids, no text - consider a <unary/> element */
  1455.             $retString .= " -->\n";
  1456.  
  1457.             return $retString;
  1458.         }
  1459.  
  1460.         /* If we get here, the element does have children... get their contents */
  1461.  
  1462.         $nextDepth = $depth+1;
  1463.  
  1464.         for ($i=0; $i < $this->xnumChildren ; $i++)
  1465.         {
  1466.             $retString .= $this->xchildren[$i]->toStringWithWhiteSpaces($nextDepth);
  1467.         }
  1468.  
  1469.         $retString .= "\n$spaces -->\n";
  1470.  
  1471.  
  1472.         return $retString;
  1473.     }
  1474.  
  1475.  
  1476.     function toStringNoWhiteSpaces ()
  1477.     {
  1478.         $retString = '';
  1479.  
  1480.         $retString = "<!-- ";
  1481.  
  1482.         if (! $this->xnumChildren)
  1483.         {
  1484.             /* No kids, no text - consider a <unary/> element */
  1485.             $retString .= " -->";
  1486.             return $retString;
  1487.         }
  1488.  
  1489.  
  1490.         /* If we get here, the element does have children... get their contents */
  1491.         for ($i=0; $i < $this->xnumChildren ; $i++)
  1492.         {
  1493.             $retString .= $this->xchildren[$i]->toStringNoWhiteSpaces();
  1494.         }
  1495.  
  1496.         $retString .= " -->";
  1497.  
  1498.  
  1499.         return $retString;
  1500.     }
  1501.  
  1502.  
  1503. }
  1504.  
  1505.  
  1506.  
  1507.  
  1508. /***************************************************************************************************
  1509. ****************************************************************************************************
  1510. *****
  1511. *****                      MiniXMLElementCData
  1512. *****
  1513. ****************************************************************************************************
  1514. ***************************************************************************************************/
  1515.  
  1516. /* The MiniXMLElementCData class is a specific extension of the MiniXMLElement class.
  1517. **
  1518. ** It is used to create the special <![CDATA [ data ]]> tags and an instance in created when calling
  1519. ** $elementObject->cdata('data');
  1520. **
  1521. ** It's methods are the same as for MiniXMLElement - see those for documentation.
  1522. **/
  1523.  
  1524. class MiniXMLElementCData extends MiniXMLElement {
  1525.  
  1526.  
  1527.  
  1528.  
  1529.     function MiniXMLElementCData ($contents)
  1530.     {
  1531.  
  1532.         $this->MiniXMLElement('CDATA');
  1533.         if (! is_null($contents))
  1534.         {
  1535.             $this->createNode($contents, 0) ;
  1536.         }
  1537.     }
  1538.  
  1539.  
  1540.     function toStringNoWhiteSpaces ()
  1541.     {
  1542.         return $this->toString(MINIXML_NOWHITESPACES);
  1543.     }
  1544.  
  1545.     function toStringWithWhiteSpaces ($depth=0)
  1546.     {
  1547.         return $this->toString($depth);
  1548.     }
  1549.  
  1550.     function toString ($depth=0)
  1551.     {
  1552.         $spaces = '';
  1553.         if ($depth != MINIXML_NOWHITESPACES)
  1554.         {
  1555.             $spaces = $this->_spaceStr($depth);
  1556.         }
  1557.  
  1558.         $retString = "$spaces<![CDATA[ ";
  1559.  
  1560.         if (! $this->xnumChildren)
  1561.         {
  1562.             $retString .= "]]>\n";
  1563.             return $retString;
  1564.         }
  1565.  
  1566.         for ( $i=0; $i < $this->xnumChildren; $i++)
  1567.         {
  1568.             $retString .= $this->xchildren[$i]->getValue();
  1569.  
  1570.         }
  1571.  
  1572.         $retString .= " ]]>\n";
  1573.  
  1574.         return $retString;
  1575.     }
  1576.  
  1577.  
  1578.  
  1579. }
  1580.  
  1581. /***************************************************************************************************
  1582. ****************************************************************************************************
  1583. *****
  1584. *****                      MiniXMLElementDocType
  1585. *****
  1586. ****************************************************************************************************
  1587. ***************************************************************************************************/
  1588.  
  1589. /* The MiniXMLElementDocType class is a specific extension of the MiniXMLElement class.
  1590. **
  1591. ** It is used to create the special <!DOCTYPE def [...]> tags and an instance in created when calling
  1592. ** $elementObject->comment('');
  1593. **
  1594. ** It's methods are the same as for MiniXMLElement - see those for documentation.
  1595. **/
  1596.  
  1597. class MiniXMLElementDocType extends MiniXMLElement {
  1598.  
  1599.     var $dtattr;
  1600.  
  1601.     function MiniXMLElementDocType ($attr)
  1602.     {
  1603.         $this->MiniXMLElement('DOCTYPE');
  1604.         $this->dtattr = $attr;
  1605.     }
  1606.     function toString ($depth)
  1607.     {
  1608.         if ($depth == MINIXML_NOWHITESPACES)
  1609.         {
  1610.             return $this->toStringNoWhiteSpaces();
  1611.         } else {
  1612.             return $this->toStringWithWhiteSpaces($depth);
  1613.         }
  1614.     }
  1615.  
  1616.  
  1617.     function toStringWithWhiteSpaces ($depth=0)
  1618.     {
  1619.  
  1620.         $spaces = $this->_spaceStr($depth);
  1621.  
  1622.         $retString = "$spaces<!DOCTYPE " . $this->dtattr . " [\n";
  1623.  
  1624.         if (! $this->xnumChildren)
  1625.         {
  1626.             $retString .= "]>\n";
  1627.             return $retString;
  1628.         }
  1629.  
  1630.         $nextDepth = $depth + 1;
  1631.  
  1632.         for ( $i=0; $i < $this->xnumChildren; $i++)
  1633.         {
  1634.  
  1635.             $retString .= $this->xchildren[$i]->toStringWithWhiteSpaces($nextDepth);
  1636.  
  1637.         }
  1638.  
  1639.         $retString .= "\n$spaces]>\n";
  1640.  
  1641.         return $retString;
  1642.     }
  1643.  
  1644.  
  1645.     function toStringNoWhiteSpaces ()
  1646.     {
  1647.  
  1648.         $retString = "<!DOCTYPE " . $this->dtattr . " [ ";
  1649.  
  1650.         if (! $this->xnumChildren)
  1651.         {
  1652.             $retString .= "]>\n";
  1653.             return $retString;
  1654.         }
  1655.  
  1656.         for ( $i=0; $i < $this->xnumChildren; $i++)
  1657.         {
  1658.  
  1659.             $retString .= $this->xchildren[$i]->toStringNoWhiteSpaces();
  1660.  
  1661.         }
  1662.  
  1663.         $retString .= " ]>\n";
  1664.  
  1665.         return $retString;
  1666.     }
  1667.  
  1668.  
  1669. }
  1670.  
  1671.  
  1672. /***************************************************************************************************
  1673. ****************************************************************************************************
  1674. *****
  1675. *****                      MiniXMLElementEntity
  1676. *****
  1677. ****************************************************************************************************
  1678. ***************************************************************************************************/
  1679.  
  1680. /* The MiniXMLElementEntity class is a specific extension of the MiniXMLElement class.
  1681. **
  1682. ** It is used to create the special <!ENTITY name "val">  tags and an instance in created when calling
  1683. ** $elementObject->comment('');
  1684. **
  1685. ** It's methods are the same as for MiniXMLElement - see those for documentation.
  1686. **/
  1687.  
  1688. class MiniXMLElementEntity extends MiniXMLElement {
  1689.  
  1690.  
  1691.  
  1692.     function MiniXMLElementEntity  ($name, $value=NULL)
  1693.     {
  1694.  
  1695.         $this->MiniXMLElement($name);
  1696.  
  1697.         if (! is_null ($value))
  1698.         {
  1699.             $this->createNode($value, 0);
  1700.         }
  1701.  
  1702.     }
  1703.  
  1704.     function toString ($depth = 0)
  1705.     {
  1706.  
  1707.         $spaces = '';
  1708.         if ($depth != MINIXML_NOWHITESPACES)
  1709.         {
  1710.             $spaces = $this->_spaceStr($depth);
  1711.         }
  1712.  
  1713.         $retString = "$spaces<!ENTITY " . $this->name();
  1714.  
  1715.         if (! $this->xnumChildren)
  1716.         {
  1717.             $retString .= ">\n";
  1718.             return $retString;
  1719.         }
  1720.  
  1721.          $nextDepth = ($depth == MINIXML_NOWHITESPACES) ? MINIXML_NOWHITESPACES
  1722.                                         : $depth + 1;
  1723.         $retString .= '"';
  1724.         for ( $i=0; $i < $this->xnumChildren; $i++)
  1725.         {
  1726.  
  1727.             $retString .= $this->xchildren[$i]->toString(MINIXML_NOWHITESPACES);
  1728.  
  1729.         }
  1730.         $retString .= '"';
  1731.         $retString .= " >\n";
  1732.  
  1733.         return $retString;
  1734.     }
  1735.  
  1736.  
  1737.     function toStringNoWhiteSpaces ()
  1738.     {
  1739.         return $this->toString(MINIXML_NOWHITESPACES);
  1740.     }
  1741.  
  1742.     function toStringWithWhiteSpaces ($depth=0)
  1743.     {
  1744.         return $this->toString($depth);
  1745.     }
  1746.  
  1747.  
  1748. }
  1749.  
  1750.  
  1751. ?>
  1752.